#include "std_functional.h"
#include "mytools.h"

Foo::Foo(int num) : num_(num) {}

void Foo::print_add(int i) const { std::cout << num_ + i << std::endl; }

void PrintNum::operator()(int num) const { std::cout << num << std::endl; }

void print_num(int num) { std::cout << num << std::endl; }

void test_std_functional() {
  print_title("Testing std::function");

  // 存储自由函数
  std::function<void(int)> f_display = print_num;
  f_display(-9);

  // 存储lambda
  std::function<void()> f_display_42 = []() { print_num(42); };
  f_display_42();

  // 存储到 std::bind 调用的结果
  std::function<void()> f_display_31337 = std::bind(print_num, 31337);
  f_display_31337();

  // 存储到成员函数的调用
  std::function<void(const Foo &, int)> f_add_display = &Foo::print_add;
  const Foo foo(314159);
  f_add_display(foo, 1);
  f_add_display(314159, 1);

  // 存储到数据成员访问器的调用
  std::function<int(Foo const &)> f_num = &Foo::num_;
  std::cout << "num_: " << f_num(foo) << '\n';

  // 存储到成员函数及对象的调用
  using std::placeholders::_1;
  std::function<void(int)> f_add_display2 = std::bind(&Foo::print_add, foo, _1);
  f_add_display2(2);

  // 存储到成员函数和对象指针的调用
  std::function<void(int)> f_add_display3 =
      std::bind(&Foo::print_add, &foo, _1);
  f_add_display3(3);

  // 存储到函数对象的调用
  std::function<void(int)> f_display_obj = PrintNum();
  f_display_obj(18);
}